package com.yingxin.yxerp.module.permission.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yingxin.yx.framework.commons.constant.CommonConst;
import com.yingxin.yx.framework.commons.enums.BusinessType;
import com.yingxin.yx.framework.commons.exception.BizException;
import com.yingxin.yx.framework.user.core.IUserSupport;
import com.yingxin.yxerp.module.oplog.aop.OplogAnnotation;
import com.yingxin.yxerp.module.permission.entity.AppPermission;
import com.yingxin.yxerp.module.permission.entity.AppRole;
import com.yingxin.yxerp.module.permission.entity.AppRolePermission;
import com.yingxin.yxerp.module.permission.mapper.AppRoleMapper;
import com.yingxin.yxerp.module.permission.service.IAppPermissionService;
import com.yingxin.yxerp.module.permission.service.IAppRolePermissionService;
import com.yingxin.yxerp.module.permission.service.IAppRoleService;
import com.yingxin.yxerp.module.permission.vo.req.helper.UserAppPermissionTreeHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 角色 服务实现类
 * @author fanchao
 * @since 2021-05-13
 */

@Service
public class AppRoleServiceImpl extends ServiceImpl<AppRoleMapper, AppRole> implements IAppRoleService {

    @Autowired
    private IUserSupport userSupport;

    @Autowired
    private IAppPermissionService appPermissionService;

    @Autowired
    private IAppRolePermissionService appRolePermissionService;

    /**
     * 新增角色
     */
    @OplogAnnotation(biz = BusinessType.ROLE, id = "{{role.id}}", action = "新增",
            desc = "角色[{{role.name}}]")
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void create(AppRole role, List<String> permissionIds) {
        checkRoleName(role.getName(), role.getId());
        save(role);
        saveAppRolePermission(role, permissionIds);
    }

    /**
     * app修改角色
     */
    @OplogAnnotation(biz = BusinessType.ROLE, id = "{{role.id}}", action = "修改",
            desc = "角色[{{role.name}}]")
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void update(AppRole role, List<String> permissionIds) {
        checkRoleName(role.getName(), role.getId());
        updateById(role);
        appRolePermissionService.deleteByRoleId(role.getId());
        saveAppRolePermission(role, permissionIds);
        // 激活权限加载
        //userSupport.activateReloadPermissions();
    }

    /**
     * 启用角色
     */
    @OplogAnnotation(biz = BusinessType.ROLE, id = "{{role.id}}", action = "启用",
            desc = "角色[{{role.name}}]")
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void enable(AppRole role) {
        UpdateWrapper<AppRole> uw = new UpdateWrapper<>();
        uw.lambda().set(AppRole::getStatus, CommonConst.TRUE);
        uw.lambda().set(AppRole::getUpdaterId, userSupport.getUserId());
        uw.lambda().eq(AppRole::getId, role.getId());
        boolean success = update(uw);
        if (!success) {
            throw new BizException("操作失败");
        }
        // 激活权限加载
       // userSupport.activateReloadPermissions();
    }

    /**
     * 禁用角色
     */
    @OplogAnnotation(biz = BusinessType.ROLE, id = "{{role.id}}", action = "禁用",
            desc = "角色[{{role.name}}]")
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void disable(AppRole role) {
        UpdateWrapper<AppRole> uw = new UpdateWrapper<>();
        uw.lambda().set(AppRole::getStatus, CommonConst.FALSE);
        uw.lambda().set(AppRole::getUpdaterId, userSupport.getUserId());
        uw.lambda().eq(AppRole::getId, role.getId());
        boolean success = update(uw);
        if (!success) {
            throw new BizException("操作失败");
        }
        // 激活权限加载
        // userSupport.activateReloadPermissions();
    }

    /**
     * 删除角色
     */
    @OplogAnnotation(biz = BusinessType.ROLE, id = "{{role.id}}", action = "删除",
            desc = "角色[{{role.name}}]")
    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void delete(AppRole role) {
        removeById(role.getId());
        appRolePermissionService.deleteByRoleId(role.getId());
        // 激活权限加载
       // userSupport.activateReloadPermissions();
    }


    /**
     * app保存角色权限
     * @param role
     * @param permissionIds
     */
    private void saveAppRolePermission(AppRole role, List<String> permissionIds) {
        if (CollectionUtil.isNotEmpty(permissionIds)) {
            // rolePermissionMap
            Map<String, AppRolePermission> rolePermissionMap = new HashMap<>();
            for (String permissionId : permissionIds) {
                rolePermissionMap.put(permissionId, new AppRolePermission(role.getId(), permissionId));
            }
            // parent
            List<AppPermission> permissions = appPermissionService.list();
            Collection<AppPermission> parentPermissions = UserAppPermissionTreeHelper.buildParent(rolePermissionMap, permissions);
            for (AppPermission parent : parentPermissions) {
                rolePermissionMap.put(parent.getId(), new AppRolePermission(role.getId(), parent.getId()));
            }
            appRolePermissionService.saveBatch(rolePermissionMap.values());
        }
    }

    public void checkRoleName(String name, String excludeId) {
        QueryWrapper<AppRole> qw = new QueryWrapper<>();
        qw.lambda().eq(AppRole::getName, name);
        if (excludeId != null) {
            qw.lambda().ne(AppRole::getId, excludeId);
        }
        List<AppRole> list = list(qw);
        if (list.size() > 0) {
            throw new BizException("名称重复");
        }
    }

}